<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.global.js"></script>
</head>
<body>
    <div id="app">
        <p>{{count}}</p>
        <p>{{doubleCount}}</p>
        <p>
            <button @click="count++">count++</button>
        </p>
        <hr>
        <p>
            {{zhang.name}}----{{zhang.age}}---{{zhang.info.height}}
        </p>
        <p>
            <button @click="zhang.age++">age++</button>
            <br>
            <button @click="zhang.info.height++">height++</button>
        </p>
    </div>
</body>
<script>
    let {createApp} = Vue;
    let {ref,reactive,readonly,computed,watch} = Vue;

    var app = createApp({
        
        setup(props) {

            let count = ref(100);  /// ref对象
            // console.log(count);

            let addCount = ()=>{
                count.value ++;
            }

            // zhang ->代理对象(响应对象)
            let zhang = reactive({// 目标对象
                name:"张三",
                age:18,
                info:{
                    height:173,
                    weight:65
                }
            });  // new Proxy(data,{get,set})
            // console.log(zhang);

            // ref对象看
            let doubleCount = computed(()=>{
                return count.value * 2;
            })
            console.log(doubleCount);

            // watch 监听 (默认是惰性的, 只有监听的数据发生改变时,才会触发监听函数)
            // watch(source,callback,options)
            // source 监听的数据(ref对象,计算属性(ref对象),getter函数(取值函数 -> 计算属性), proxy对象,以上类型的值组成的数组)
            // callback  监听的数据改变时触发的函数
            // options 
            //      deep:true  深度监听
            //      immediate:true  初始化阶段立即执行
            //      flush: "pre" / "post" / "sync"  

            // 1. 监听ref对象(ref 计算属性)
            watch(count,function(newVal,oldVal){
                console.log("count发生改变",newVal,oldVal);
            })

            watch(doubleCount,function(newVal,oldVal){
                console.log("doubleCount发生改变",newVal,oldVal);
            })

            // 计算属性可以直接简写成箭头函数
            // 1. 先根据函数的返回值 得到计算属性(模板中无法使用)
            // 2. 如果依赖的数据发生改变, 得到的计算属性也会跟着改变
            // watch(()=>count.value * 3,function(newVal,oldVal){
            //     console.log("tripleCount发生改变",newVal,oldVal);
            // })

            // 2. 监听代理对象 (当直接侦听一个响应式对象时，侦听器会自动启用深层模式,如果是ref对象, value值中存储的数据也是一个对象,不会自动启用深层模式)

            // 2.1 直接监听对象会有问题   newVal,oldVal引用同一片内存空间, 打印内容一样
            // watch(zhang,function(newVal,oldVal){
            //     console.log("zhang发生改变",newVal,oldVal);
            // })

            // 监听对象属性的变化
            // watch(()=>JSON.parse(JSON.stringify(zhang)),function(newVal,oldVal){
            //     console.log("zhang发生改变",newVal,oldVal);
            // })

            // 监听对象某个属性的变化
            // watch(()=>zhang.age,function(newVal,oldVal){
            //     console.log("zhang.age发生改变",newVal,oldVal);
            // })

            //  监听对象某些属性的变化  (传入一个数组,数组中存有多个计算属性)
            watch([()=>zhang.name,()=>zhang.age],function([newName,newAge],[oldName,oldAge]){
                console.log("zhang的属性发生改变",newName,oldName);
                console.log("zhang的属性发生改变",newAge,oldAge);
            })






            


            return {
                // 键名: 传递出去的数据名 方法名  计算属性
                count:count,
                doubleCount,
                addCount,
                zhang,
            }
            
        },
        mounted() {
            // console.log("this",this);
        },
        watch:{
            // "zhang":function(){},
            // "zhang.age":function(){},
        }
        
    })

    app.mount("#app");








</script>
</html>